#ifndef REGULAREXPERSSION_H
#define REGULAREXPERSSION_H
#include "Operand.h"

class RegularExpression : public Operand{
private:
    
    Operand *operand_one=nullptr;
    Operand *operand_two=nullptr;
    LexemeCategory category;      // 词的category属性值
    char op_symbol;  //正则运算符，共有7种：‘=’, ‘~’，‘-’, ‘|’，‘.’, ‘*’,  ‘+’,  ‘?’ 
    string name;

    void merge_two_operand(Operand *one , char op, Operand *two){
        //这里我们认为 - 是连接的意思， a-b  --> ab
        //assert(op=='|' || op== '-');

        if(&this->pNFA != one->get_graph()){
            this->pNFA=*(one->get_graph());
        }
        switch (op)
        {
        case '|':
            this->pNFA.union_graph(two->get_graph());
            break;
        case '-':
            this->pNFA.link_graph_b(two->get_graph());
            break;
        
        default:
            break;
        }

        
    
    };

    void merge_one_operand(Operand *one , char op){
        if(&pNFA != one->get_graph()){
            this->pNFA=*(one->get_graph());
        };
        switch (op)
        {
        case '*':
            this->pNFA.closure_graph();
            break;
        case '+':
            this->pNFA.plus_closure_graph();
            break;
        case '?':
            this->pNFA.zero_or_one_graph();
            break;
        default:
            break;
        }
    }

public:

    OperandType resultType;  //运算结果的类型
    
    Graph pNFA;       //对应的NFA


    void closure_regular(){
        //对自己进行闭包运算
        merge_one_operand(this,'*');
    }

    void plus_closure_regular(){
        merge_one_operand(this,'+');
    }

    void zero_or_one_regular(){
        merge_one_operand(this , '?');
    }

    void union_regular(Operand *one){
        //将自己和one 作 | 运算
        merge_two_operand(this,'|',one);
    }

    void link_regular(Operand *one){
        //将自己和one 作 - 运算
        merge_two_operand(this,'-',one);
    }

    RegularExpression(Operand *one){
        if(&this->pNFA != one->get_graph()){
            this->pNFA=*(one->get_graph());
        }
    }

    RegularExpression(Operand *one , char op){
        assert(op=='*'||op=='+'||op=='?');
        operand_one=one;
        op_symbol=op;
        merge_one_operand(one,op);
    }

    RegularExpression(Operand *one , char op, Operand *two){
        assert(op=='|' || op=='-');
        operand_one=one;
        operand_two=two;
        op_symbol=op;
        merge_two_operand(one ,op,two);
    }


    OperandType get_operand_type() override{
        return OperandType::REGULAR;
    }

    string get_info() const override{
        return name;
    }

    Graph *get_graph(){
        return &pNFA;
    }

};

#endif